/*
 * Log.cpp
 *
 *  Created on: Aug 12, 2014
 *      Author: burek
 */

#include <cstdarg>
#include <cstring>
#include <cstdio>
#include <iostream>

#include "../../_config.h"
#include "../types/integers.h"
#include "../portutil/timing.h"
#include "Log.h"

#ifdef ANDROID
#include <android/log.h>
#endif

char _logBuffer[LOG_LINE_LENGTH];
char _logBuffer2[LOG_LINE_LENGTH];
char _logBuffer3[LOG_LINE_LENGTH];
FILE * _logF = NULL;
uint32_t _startTicks;
bool _logTiming = false;
void (*_cbfunc)(const char *) = NULL;

int _logHistRobin = 0;

char _logHistory[LOG_LINES][LOG_LINE_LENGTH];

const char * getLogLine(int n)
{
	if(n >= 0 && n <= LOG_LINES)
		return _logHistory[(_logHistRobin - n - 1) & (LOG_LINES - 1)];
	else
		return NULL;
}

void setLogCallback(void (*func)(const char *))
{
	_cbfunc = func;
}

void startLogTiming()
{
	_logTiming = true;
	_startTicks = cu_getTickCount();
}

void _log(const char * msg)
{
	uint32_t delta = _logTiming ? cu_getTickCount() - _startTicks : 0;
	if(_cbfunc != NULL) _cbfunc(msg);
	snprintf(_logBuffer3, LOG_LINE_LENGTH, "%4u.%03u | %s\n", delta / 1000, delta % 1000, msg);

#ifndef WIN32
	std::cout << msg << "\n";
#endif

	if(_logF)
	{
		fputs(_logBuffer3, _logF);
		fflush(_logF);
	}
#ifdef ANDROID
	__android_log_print(ANDROID_LOG_INFO, "RevLog", msg);
	fflush(_logF);
#endif

	strcpy(_logHistory[_logHistRobin], _logBuffer3);
	_logHistRobin = (_logHistRobin + 1) % LOG_LINES;
}

int getLogLineCount()
{
	return LOG_LINES;
}

void RLog(const char * fmt, ...)
{
	va_list argp;
	va_start(argp, fmt);
	vsprintf(_logBuffer, fmt, argp);
	va_end(argp);
	_log(_logBuffer);
}

void RInfo(const char * fmt, ...)
{
#ifdef DEBUG
	va_list argp;
	va_start(argp, fmt);
	vsprintf(_logBuffer, fmt, argp);
	va_end(argp);
	_log(_logBuffer);
#endif
}

void RError(const char * fmt, ...)
{
	va_list argp;
	va_start(argp, fmt);
	vsprintf(_logBuffer2, fmt, argp);
	va_end(argp);
	strcpy(_logBuffer, "[ERROR] ");
	strcat(_logBuffer, _logBuffer2);
	_log(_logBuffer);
}

void ROpenLogFile(const char * fileName)
{
	memset(_logHistory, 0, LOG_LINES * LOG_LINE_LENGTH);
	_logHistRobin = 0;

	//_startTicks = cu_getTickCount();
	_logF = fopen(fileName, "wt");

	if(_logF)
	{
		RLog("Rev4 engine on %s (%d bit)", OS_NAME, sizeof(void*) * 8);
		RLog("(%s build %s %s w/ %s)",
#ifdef DEBUG
				"debug"
#else
				"release"
#endif
				,__DATE__, __TIME__, RCOMPILER_NAME);
		RLog("=========================================================");
		RInfo("Log file \"%s\" opened.", fileName);
	}
	else
	{
		RError("Couldn't open \"%s\" for logging.", fileName);
	}
}

void RCloseLog()
{
	if(_logF)
	{
		RInfo("Log closed.");
		fclose(_logF);
		_logF = NULL;
	}
	else
	{
		RError("Log file isn't open.");
	}
}


